package com.cgwx.tcservice.utils;

import com.cgwx.commonutils.DataTypeConvertUtils;
import com.cgwx.tcservice.config.DataConfig;
import com.cgwx.tcservice.entity.bean.TcSendParam;
import com.cgwx.tcservice.entity.tc.TcCommandConfig;
import com.cgwx.tcservice.entity.tc.TcParameterConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;

/**
 * @author GaoWei
 * @Date 2023/9/19 - 13:36
 */

@Component
public class SendDataAnalysis {

    @Autowired
    private DataConfig dataConfig;

//    发送帧组包
    public String sendDataFraming(TcSendParam tcSendParam){
//        得到前端传递的遥控指令对象，和表单对象（包括指令类型、执行时间（真正采取的执行时间再遥控指令对象的执行时间参数）、遥控参数（不是查库，是查静态变量得到的））
        TcCommandConfig tcCommandConfig = tcSendParam.getTcSendCommand();
        ArrayList<TcParameterConfig> tcParameterConfigArrayList = tcSendParam.getTcSendForm().getParameters();

//        在配置文件中得到参数信息
        String frameSyncWord = dataConfig.getFrame_sync_word();
        String frameModeWord = dataConfig.getFrame_mode_word();
        String satelliteId = dataConfig.getSatellite_id();
//        待发送的注入数据字符串（CAN为88字节，176字符; S为128字节，256字符）
//        首先组成帧同步字、帧方式字、帧头（卫星id + 帧长 + 明密态）：共8字节
        String sendData = frameSyncWord + frameModeWord + satelliteId + "007C" + "02";

//        加解密区数据填充
        if("s".equalsIgnoreCase(tcSendParam.getTcSendChannel())){
//            如果是S通路，需要增加40字节加解密区
            sendData = sendData + "AA".repeat(40);
        }

//        其次组成数据区内容
//        指令序号
        String tcNumber = tcCommandConfig.getTcNumber();
//        部件代码
        String tcComponentCode = tcCommandConfig.getTcComponentCode();
//        指令编码
        String tcEncoding = tcCommandConfig.getTcEncoding();

//        继续组帧
        sendData = sendData + tcNumber + tcComponentCode + tcEncoding;

//        指令类型码（00H：立即执行的固定参数指令; 01H：立即执行的可变参数指令; 10H：延时执行的固定参数指令; 11H：延时执行的可变参数指令）
//        tcCommandType = 00 为固定参数指令，01 为可变参数指令
        String tcCommandType = tcCommandConfig.getTcCommandType();
//        指令执行时间秒
        String tcExecutionTime = tcCommandConfig.getTcExecutionTime();
        if("AAAAAAAA".equals(tcExecutionTime)){
//            说明是立即执行指令
            if("00".equals(tcCommandType)){
//                立即执行的固定参数指令
                sendData = sendData + "00" + tcExecutionTime;
            }else{
//                立即执行的可变参数指令
                sendData = sendData + "01" + tcExecutionTime;
            }
        }else{
//            说明是延时执行指令
            if("00".equals(tcCommandType)){
//                延时执行的固定参数指令
                sendData = sendData + "10" + DataTypeConvertUtils.FullStr0(DataTypeConvertUtils.Dec_to_Hex(tcExecutionTime),8);
            }else{
//                延时执行的可变参数指令
                sendData = sendData + "11" + DataTypeConvertUtils.FullStr0(DataTypeConvertUtils.Dec_to_Hex(tcExecutionTime),8);
            }
        }

//        定义一些变量
//        指令参数内容（注入指令共70字节）
        String commandParam = "";
//        指令参数长度定义
        int commandParamLength = 140;
//        校验和本身长度
        int checksumLength = 0;
//        需要校验多长的数据
        int checksumOfParamBitLength = 0;
//        参数长度临时变量
        int paramLength_tmp = 0;
//        二进制字符串临时变量
        StringBuilder bit_str_tmp = new StringBuilder();
//        CRC
        String crc;
//        待校验的字符串
        String crcInfoString;


//        遍历所有指令参数
        for (int i = 0; i < tcParameterConfigArrayList.size(); i++) {
            TcParameterConfig tcParameterConfig = tcParameterConfigArrayList.get(i);
//            以下各种处理方式得到的临时指令参数，十六进制字符串
            String commandParam_tmp = "";
//            参数类型为"十六进制"
            if (tcParameterConfig.getTcParameterType() == 1) {
                String tcParameterValue = "";
//                参数不够一个字节
                if (tcParameterConfig.getTcParameterLength() < 8) {
//                    多个参数凑够了一字节
                    if (paramLength_tmp + tcParameterConfig.getTcParameterLength() == 8) {
                        handleTcParamHexByBin(bit_str_tmp, tcParameterConfig);
//                        转换为16进制
                        tcParameterValue = DataTypeConvertUtils.Binary_to_Hex(bit_str_tmp.toString()).toUpperCase();
//                        清空临时变量
                        paramLength_tmp = 0;
                        bit_str_tmp = new StringBuilder();
                    }
//                    暂时没有凑够一个字节，拼接二进制字符
                    else
                    {
//                        记录当前参数长度（位置）
                        paramLength_tmp += tcParameterConfig.getTcParameterLength();
//                        固定值，组合为（1，1）
                        handleTcParamHexByBin(bit_str_tmp, tcParameterConfig);
                    }
                }
//                参数大于等于一个字节
                else {
//                    固定值，组合为（1，1），直接取表中的String的ValueD，组合为（1，1）
                    if (tcParameterConfig.getTcParameterMode() == 1) {
                        if ((tcParameterConfig.getTcParameterValueD() != null) && (!"".equals(tcParameterConfig.getTcParameterValueD()))) {
                            tcParameterValue = tcParameterConfig.getTcParameterValueD().trim();
                        }
                    }
//                    补码，组合为（1，2）
                    if (tcParameterConfig.getTcParameterMode() == 2) {
//                        处理方法
                        tcParameterValue = handleTcParamModeIsTwo(tcParameterConfig, tcParameterValue);
//                        对参数长度进行判断，不够的补0，一般用不上
                        tcParameterValue = judgeParamLength(i, tcParameterConfig, tcParameterValue);
                    }
                }
//                得到所有指令参数值（tcParameter）
                commandParam_tmp = tcParameterValue.toUpperCase();
//                取整，主要是公式和单精度能用到
                if (commandParam_tmp.contains(".")) {
                    commandParam_tmp = commandParam_tmp.substring(0, commandParam_tmp.indexOf("."));
                }
            }
//            参数类型为"公式"
            if (tcParameterConfig.getTcParameterType() == 2) {
                double result = 0.0D;
                String resultStr;
//                将参数转换类型，可能为null
                BigDecimal bigDecimalTcParameterValue = new BigDecimal(tcParameterConfig.getTcParameterValueD());
//                组合为（2,2），公式必为补码，参数长度不够一字节
                if (tcParameterConfig.getTcParameterLength() < 8) {
//                    多个参数凑够一字节
                    if (paramLength_tmp + tcParameterConfig.getTcParameterLength() == 8) {
                        String binStr = handleTcParamByte(tcParameterConfig, bigDecimalTcParameterValue, result);
//                        结果不够一字节
                        if (binStr.length() < 8) {
                            binStr = DataTypeConvertUtils.FullBinary(binStr, 8);
                        }
                        bit_str_tmp.append(binStr.substring(binStr.length() - tcParameterConfig.getTcParameterLength()));
//                        指令参数的临时结果
                        commandParam_tmp = DataTypeConvertUtils.Binary_to_Hex(bit_str_tmp.toString()).toUpperCase();
//                        清空中间变量
                        paramLength_tmp = 0;
                        bit_str_tmp = new StringBuilder();
                    }
                    else
                    {
                        paramLength_tmp += tcParameterConfig.getTcParameterLength();
                        String binStr = handleTcParamByte(tcParameterConfig, bigDecimalTcParameterValue, result);
                        bit_str_tmp.append(binStr.substring(binStr.length() - tcParameterConfig.getTcParameterLength()));
                    }
                }
//                组合为（2,2），公式必为补码，参数长度大于等于一字节
                else
                {
                    if (tcParameterConfig.getTcHandleParam() != null) {
                        try {
//                            对（2，1）组合进行判断，正常不会出现
                            if (tcParameterConfig.getTcParameterMode() == 1) {
                                result = bigDecimalTcParameterValue.doubleValue();
                            }
                            else if ((tcParameterConfig.getTcHandleParam().toLowerCase().contains("x")) && (tcParameterConfig.getTcParameterType() == 2)) {
                                if ("x".equalsIgnoreCase(tcParameterConfig.getTcHandleParam())) {
                                    try {
                                        result = bigDecimalTcParameterValue.doubleValue();
                                    }
                                    catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                } else {
                                    result = DataTypeConvertUtils.formula(tcParameterConfig.getTcHandleParam(), bigDecimalTcParameterValue.floatValue());
                                }
                            }
                            else {
                                result = bigDecimalTcParameterValue.doubleValue();
                            }
                        }
                        catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    BigDecimal bigDecimal = new BigDecimal(result);
                    resultStr = bigDecimal.toString();
                    if (resultStr.contains(".")) {
                        commandParam_tmp = DataTypeConvertUtils.Dec_to_Hex(resultStr.substring(0, resultStr.indexOf("."))).toUpperCase();
                    } else {
                        commandParam_tmp = DataTypeConvertUtils.Dec_to_Hex(resultStr).toUpperCase();
                    }
//                    以上处理与不足一字节一致
                    int tcParameterCharLength = tcParameterConfig.getTcParameterLength() / 8 * 2;
//                    对结果做判断，保证字节数的前提下，前后补0，正常情况下，此判断条件不成立。
                    if (commandParam_tmp.length() < tcParameterCharLength) {
                        String tmp0 = "";
                        for (int j = 0; j < tcParameterCharLength - commandParam_tmp.length(); j++) {
                            tmp0 = tmp0 + "0";
                        }
                        commandParam_tmp = tmp0 + commandParam_tmp;
                    }
                    if (commandParam_tmp.length() > tcParameterCharLength) {
                        commandParam_tmp = commandParam_tmp.substring(commandParam_tmp.length() - tcParameterCharLength);
                    }
                }
            }
//            参数类型为"二进制"
            if (tcParameterConfig.getTcParameterType() == 3) {
                String tcParameterValue = "";
//                二进制，不够一字节，很常见
                if (tcParameterConfig.getTcParameterLength() < 8) {
//                    凑够一字节
                    if (paramLength_tmp + tcParameterConfig.getTcParameterLength() == 8) {
                        handleTcParamBin(bit_str_tmp, tcParameterConfig);
                        tcParameterValue = DataTypeConvertUtils.Binary_to_Hex(bit_str_tmp.toString()).toUpperCase();
                        paramLength_tmp = 0;
                        bit_str_tmp = new StringBuilder();
                    }
//                    没有凑够一字节
                    else {
                        paramLength_tmp += tcParameterConfig.getTcParameterLength();
                        handleTcParamBin(bit_str_tmp, tcParameterConfig);
                    }
                }
//                参数长度大于一字节
                else {
//                    二进制，固定值；组合为（3,1）
                    if (tcParameterConfig.getTcParameterMode() == 1) {
                        if ((tcParameterConfig.getTcParameterValueD() != null) && (!"".equals(tcParameterConfig.getTcParameterValueD()))) {
                            tcParameterValue = tcParameterConfig.getTcParameterValueD().trim();
                        }
                    }
//                    二进制，补码；组合为（3,2）
                    if (tcParameterConfig.getTcParameterMode() == 2) {
//                        处理方法
                        tcParameterValue = handleTcParamModeIsTwo(tcParameterConfig, tcParameterValue);
//                        对参数长度进行判断，不够的补0，一般用不上
                        tcParameterValue = judgeParamLength(i, tcParameterConfig, tcParameterValue);
                        tcParameterValue = DataTypeConvertUtils.Binary_to_Hex(tcParameterValue).toUpperCase();
                    }
                }
                commandParam_tmp = tcParameterValue.toUpperCase();
            }
//            参数类型为"前校验码"，即此参数为前面若干参数的校验和
            if (tcParameterConfig.getTcParameterType() == 4) {
//                传进去指令参数，前面多少bit的校验，校验本身占的长度
                commandParam_tmp = getChecksumBefore(commandParam, Integer.parseInt(tcParameterConfig.getTcHandleParam()), tcParameterConfig.getTcParameterLength());
            }
//            参数类型为"后校验和"，即此参数为后面若干参数的校验和
            if (tcParameterConfig.getTcParameterType() == 5) {
                try {
//                    后校验和本身占的bit数
                    checksumLength = tcParameterConfig.getTcParameterLength();
//                    后校验和要校验后面多少bit数
                    checksumOfParamBitLength = Integer.parseInt(tcParameterConfig.getTcHandleParam());
                }
                catch (Exception localException1) {}
//                插入X占位
                commandParam_tmp = commandParam_tmp + "X";
            }
//            参数类型为"单精度浮点数"
            if (tcParameterConfig.getTcParameterType() == 6) {
                float result = 0.0F;
                String resultStr = "";
//                将参数转换类型，可能为null
                BigDecimal bigDecimalTcParameterValue = new BigDecimal(tcParameterConfig.getTcParameterValueD());
//                不够一个字节
                if (tcParameterConfig.getTcParameterLength() < 8) {
//                    多个参数凑够一个字节
                    if (paramLength_tmp + tcParameterConfig.getTcParameterLength() == 8) {
                        if (tcParameterConfig.getTcHandleParam() != null) {
                            result = bigDecimalTcParameterValue.floatValue();
                        }
                        bit_str_tmp.append(Integer.toHexString(Float.floatToIntBits(result)).toUpperCase());
                        commandParam_tmp = bit_str_tmp.toString();
                        paramLength_tmp = 0;
                        bit_str_tmp = new StringBuilder();
                    }
//                    暂时未凑够一个字节
                    else {
                        paramLength_tmp += tcParameterConfig.getTcParameterLength();
                        if (tcParameterConfig.getTcHandleParam() != null) {
                            try {
                                result = bigDecimalTcParameterValue.floatValue();
                            }
                            catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        bit_str_tmp.append(Integer.toHexString(Float.floatToIntBits(result)).toUpperCase());
                    }
                }
//                参数大于一个字节
                else {
                    if (tcParameterConfig.getTcHandleParam() != null) {
                        try {
                            result = bigDecimalTcParameterValue.floatValue();
                        }
                        catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    commandParam_tmp = Integer.toHexString(Float.floatToIntBits(result)).toUpperCase();
//                    检查长度够不够,可以进行补0
                    int tcParameterCharLength;
                    tcParameterCharLength = tcParameterConfig.getTcParameterLength() / 8 * 2;
                    if (commandParam_tmp.length() < tcParameterCharLength) {
                        String tmp0 = "";
                        for (int j = 0; j < tcParameterCharLength - commandParam_tmp.length(); j++) {
                            tmp0 = tmp0 + "0";
                        }
                        commandParam_tmp = tmp0 + commandParam_tmp;
                    }
                    if (commandParam_tmp.length() > tcParameterCharLength) {
                        commandParam_tmp = commandParam_tmp.substring(commandParam_tmp.length() - tcParameterCharLength);
                    }
                }
            }
//            低位在前,做一下参数转换
            if (tcParameterConfig.getTcParameterBitType() == 1) {
                commandParam_tmp = DataTypeConvertUtils.LowUp(commandParam_tmp);
            }
            commandParam = commandParam + commandParam_tmp;
        }

//        有后校验和需要计算，如果没有后校验和，则为0
        if (checksumLength > 0) {
            commandParam = getChecksumAfter(commandParam, checksumOfParamBitLength, checksumLength);
        }
//        根据指令长度补齐后续字节
//        宽带协议，注入指令共88字节（不算40字节加解密）
//        帧同步2+方式字1+帧头5 共8字节，遥控数据域80字节
//        遥控数据域中：指令序号 + 部件代码 + 指令编码 + 指令类型码 + 执行时间秒 = 8字节 CRC = 2字节，所以指令参数部分共70字节
        if(commandParam.length() < commandParamLength){
//            参数长度不够，补齐后面的参数
            commandParam = FullStrBack(commandParam,commandParamLength);
        }
//        CAN路：16字节 + 70字节数据
//        S路：56字节 + 70字节数据
        sendData = sendData + commandParam;
//        取出需要计算CRC的72字节
        if("s".equalsIgnoreCase(tcSendParam.getTcSendChannel())) {
            crcInfoString = sendData.substring(96);
        }else{
            crcInfoString = sendData.substring(16);
        }
        crc = DataTypeConvertUtils.CRC16(DataTypeConvertUtils.Hex_to_Byte(crcInfoString));
//        最终的88字节/128字节
        sendData = sendData + crc;
        return sendData;
    }

//    在后面补齐AA
    private String FullStrBack(String commandParam, int commandParamLength) {
        if (commandParam.length() < commandParamLength) {
            return commandParam + "A".repeat(commandParamLength - commandParam.length());
        }
        return commandParam;
    }

    private void handleTcParamBin(StringBuilder bit_str_tmp, TcParameterConfig tcParameterConfig) {
//        二进制，固定值；组合为（3,1）
        if (tcParameterConfig.getTcParameterMode() == 1) {
//            填满参数长度的0
            if ((tcParameterConfig.getTcHandleParam() == null) || ("".equals(tcParameterConfig.getTcHandleParam()))) {
//                只要配置正确，则不会为空或者null
                bit_str_tmp.append(DataTypeConvertUtils.FullStr0("", tcParameterConfig.getTcParameterLength()));
            }
            else {
                bit_str_tmp.append(DataTypeConvertUtils.FullStr0(tcParameterConfig.getTcHandleParam().trim(), tcParameterConfig.getTcParameterLength()));
            }
        }
//        二进制，补码；组合为（3,2）
        if (tcParameterConfig.getTcParameterMode() == 2) {
            if ((tcParameterConfig.getTcParameterValueD() == null) || ("".equals(tcParameterConfig.getTcParameterValueD()))) {
//                没发过数的，填空字符
                bit_str_tmp.append(DataTypeConvertUtils.FullStr0("", tcParameterConfig.getTcParameterLength()));
            }
            else {
//                发过数的，取其填的值
                bit_str_tmp.append(DataTypeConvertUtils.FullStr0(tcParameterConfig.getTcParameterValueD().trim(), tcParameterConfig.getTcParameterLength()));
            }
        }
    }

    private void handleTcParamHexByBin(StringBuilder bit_str_tmp, TcParameterConfig tcParameterConfig) {
//        固定值，组合为（1，1），直接取处理参数
        if (tcParameterConfig.getTcParameterMode() == 1) {
            if ((tcParameterConfig.getTcHandleParam() != null) && (!"".equals(tcParameterConfig.getTcHandleParam()))) {
                String binStr = DataTypeConvertUtils.Hex_to_Binary(tcParameterConfig.getTcHandleParam().trim());
                bit_str_tmp.append(binStr.substring(binStr.length() - tcParameterConfig.getTcParameterLength()));
            }
        }
//        补码，组合为（1，2），拼接TcParameterValueD中的值（itemdval_str String类型，itemdval中的值）
        if (tcParameterConfig.getTcParameterMode() == 2) {
//            没发过的参数，此处即为空，发过的为用户上一次
            if ((tcParameterConfig.getTcParameterValueD() != null) && (!"".equals(tcParameterConfig.getTcParameterValueD()))) {
                String binStr = DataTypeConvertUtils.Hex_to_Binary(tcParameterConfig.getTcParameterValueD().trim());
                bit_str_tmp.append(binStr.substring(binStr.length() - tcParameterConfig.getTcParameterLength()));
            }
        }
    }

    private String handleTcParamByte(TcParameterConfig tcParameterConfig, BigDecimal bigDecimalTcParameterValue, double result) {
        String resultStr;
        if (tcParameterConfig.getTcHandleParam() != null) {
            try {
//                固定值，这种情况应该没有
                if (tcParameterConfig.getTcParameterMode() == 1) {
                    result = bigDecimalTcParameterValue.doubleValue();
                }
//                公式，只有这种组合
                else if ((tcParameterConfig.getTcHandleParam().toLowerCase().contains("x")) && (tcParameterConfig.getTcParameterType() == 2)) {
//                    公式中就是一个x
                    if ("x".equalsIgnoreCase(tcParameterConfig.getTcHandleParam())) {
//                    ValueD转为BigDecimal的值，作为结果
                        result = bigDecimalTcParameterValue.doubleValue();
                    }
//                    调用公式
                    else {
//                        否则进行公式解析
                        result = DataTypeConvertUtils.formula(tcParameterConfig.getTcHandleParam(), bigDecimalTcParameterValue.floatValue());
                    }
                }
//                公式，但是没有x，直接填写发啥，改为浮点数
                else {
                    result = bigDecimalTcParameterValue.doubleValue();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        BigDecimal bigDecimal = new BigDecimal(result);
        resultStr = bigDecimal.toString();
        String binStr;
        if (resultStr.contains(".")) {
            binStr = DataTypeConvertUtils.Dec_to_Binary(resultStr.substring(0, resultStr.indexOf("."))).toUpperCase();
        }
        else {
            binStr = DataTypeConvertUtils.Dec_to_Binary(resultStr).toUpperCase();
        }
        return binStr;
    }

    private String handleTcParamModeIsTwo(TcParameterConfig tcParameterConfig, String tcParameterValue) {
        if ((tcParameterConfig.getTcParameterValueD() != null) && (!"".equals(tcParameterConfig.getTcParameterValueD()))) {
//            取用户填过的数
            tcParameterValue = tcParameterConfig.getTcParameterValueD().trim();
//            暂未填过数，配置表时和处理方式写一样的值，也可能是校验和的占位符
            if ("X".equalsIgnoreCase(tcParameterValue)) {
                tcParameterValue = "";
            }
        }
        return tcParameterValue;
    }

    private String judgeParamLength(int i, TcParameterConfig tcParameterConfig, String tcParameterValue) {
//        参数字符数（字节数 * 2）
        int tcParameterCharLength = tcParameterConfig.getTcParameterLength() / 8 * 2;
//        第一组参数且起始位置不是0 这个应该也出现不了，进行前后补零
        if ((i == 0) && (tcParameterConfig.getTcParameterStartPos() > 0)) {
            for (int j = 0; j < tcParameterConfig.getTcParameterStartPos() / 8 * 2; j++) {
                tcParameterValue = "0" + tcParameterValue;
            }
            if (tcParameterValue.length() < tcParameterCharLength) {
                int len = tcParameterCharLength - tcParameterValue.length();
                for (int j = 0; j < len; j++) {
                    tcParameterValue = tcParameterValue + "0";
                }
            }
        }
//        补0，这个应该也出现不了，进行前后补零
        else if (tcParameterValue.length() < tcParameterCharLength) {
            int len = tcParameterCharLength - tcParameterValue.length();
            for (int j = 0; j < len; j++) {
                tcParameterValue = tcParameterValue + "0";
            }
        }
        return tcParameterValue;
    }

    /**
     * 前校验和
     * @param tcParamString 待校验的指令参数字符串
     * @param checksumOfParamBitLength 前面多少bit的校验
     * @param checksumLength 校验本身占多少bit
     * @return 处理后的前校验和
     */
    public String getChecksumBefore(String tcParamString, int checksumOfParamBitLength, int checksumLength) {
        String returnStr;
        int strLen;
        try {
//            因为是字符，所以除4
            strLen = checksumOfParamBitLength / 4;
//            取出待校验的子字符串
            returnStr = tcParamString.substring(tcParamString.length() - strLen);
            returnStr = DataTypeConvertUtils.getCheckSumByString(returnStr, checksumLength);
        }
        catch (Exception e) {
            returnStr = "";
        }
        return returnStr;
    }

    /**
     * 后校验和
     * @param tcParamString 待校验的指令参数字符串
     * @param checksumOfParamBitLength 后面多少bit的校验
     * @param checksumLength 校验本身占多少bit
     * @return 处理后的后校验和
     */
    public String getChecksumAfter(String tcParamString, int checksumOfParamBitLength, int checksumLength) {
        String returnStr;
        int endLen;
        try {
            endLen = checksumOfParamBitLength / 4;
            try {
                returnStr = tcParamString.substring(tcParamString.indexOf("X") + 1, tcParamString.indexOf("X") + 1 + endLen);
            }
            catch (Exception e) {
                returnStr = tcParamString;
            }
            returnStr = DataTypeConvertUtils.getCheckSumByString(returnStr, checksumLength);
            returnStr = tcParamString.replaceAll("X", returnStr);
        }
        catch (Exception e) {
            returnStr = "";
        }
        return returnStr;
    }

}
